home *** CD-ROM | disk | FTP | other *** search
- From: dfs@doe.carleton.ca (David F. Skoll)
- Newsgroups: comp.sources.misc
- Subject: v17i003: remind - A replacement for calendar, Part01/04
- Message-ID: <1991Feb19.162725.16131@sparky.IMD.Sterling.COM>
- Date: 19 Feb 91 16:27:25 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: 82b040d5 c245498c 552796f6 062f4573
-
- Submitted-by: David F. Skoll <dfs@doe.carleton.ca>
- Posting-number: Volume 17, Issue 3
- Archive-name: remind/part01
-
- Remind is a sophisticated replacement for calendar(1). It features
- advanced date calculation routines, sophisticated handling of holidays,
- and "timed reminders" which you can set to pop up on your screen at specific
- times. It also allows administrators to create system-wide reminders and
- have reminders mailed automatically to users.
-
- Remind has been successfully compiled on Sun 3 and Sun 4 machines under
- SunOS 4.0 and 4.1, on a 386-Xenix machine, under MS-DOS on an XT, on
- an Apollo workstation, and on various other SYSV and BSD machines.
-
- David F. Skoll
- --
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # If this archive is complete, you will see the following message at the end:
- # "End of archive 1 (of 4)."
- # Contents: README.DOS README.UNIX nextdate.c remind.1
- # Wrapped by kent@sparky on Tue Feb 19 10:16:40 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'README.DOS' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README.DOS'\"
- else
- echo shar: Extracting \"'README.DOS'\" \(1206 characters\)
- sed "s/^X//" >'README.DOS' <<'END_OF_FILE'
- XREMIND 2.3 for MS-DOS
- X
- XFirst, read the files COPYRIGHT and WHATSNEW.23.
- X
- XREMIND was originally written for MS-DOS. To compile it, you need the
- XMicrosoft C compiler (at least version 5.1) and the Microsoft MAKE
- Xutility.
- X
- XBefore compiling the software, check if it includes patches. These are
- Xfiles called patch.xx. If there are patches, apply them all by typing
- X
- Xcat patch.* | patch
- X
- Xon a Unix machine. Then copy the software to your MS-DOS machine.
- X
- XTo compile the software, simply go to the source directory and type:
- X
- XMAKE REMIND.MAK
- X
- XThe file test.rem contains test reminders for verifying that REMIND's
- Xdate calculation routines are working correctly. The file test.out
- Xcontains the result of running: remind -dv test.rem 16 feb 1991
- X
- XNote that the MS-DOS version of REMIND operates slightly differently from
- Xthe UNIX version: MS-DOS has no concept of file access date. Thus, to
- Ximplement the "ONCE" keyword, REMIND will change the modification date
- Xof the top-level reminder file after it has run. This is equivalent to
- Xperforming a "touch" of the file after running REMIND.
- X
- XAlso, the MS-DOS version does not queue AT reminders for timed activation.
- X--
- XDavid F. Skoll <dfs@doe.carleton.ca>
- X
- END_OF_FILE
- if test 1206 -ne `wc -c <'README.DOS'`; then
- echo shar: \"'README.DOS'\" unpacked with wrong size!
- fi
- # end of 'README.DOS'
- fi
- if test -f 'README.UNIX' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README.UNIX'\"
- else
- echo shar: Extracting \"'README.UNIX'\" \(2180 characters\)
- sed "s/^X//" >'README.UNIX' <<'END_OF_FILE'
- XREMIND version 2.3 for UNIX
- X
- XFirst, read the files COPYRIGHT and WHATSNEW.23
- X
- XBefore compiling the software, check if it includes patches. These
- Xare files called patch.xx. If there are patches, apply them all by
- Xtyping
- X
- Xcat patch.* | patch
- X
- XNext, examine the Makefile and change any parameters which need to be
- Xchanged for your system. As it stands, the Makefile is set up for a
- XBSD system.
- X
- XTo compile REMIND, just go to the source directory and type "make".
- XThis creates the executable file "remind". You can type "make CC=gcc"
- Xif you want to use the Gnu C Compiler, or you can edit the Makefile to
- Xmake gcc the default.
- X
- XThe file test.rem contains test reminders for verifying that REMIND's
- Xdate calculation routines are working correctly. The file test.out
- Xcontains the result of running: remind -dv test.rem 16 feb 1991
- X
- XREMIND has been compiled on Sun3s and Sun4s under Sun OS 4.0, on an
- XIBM PC under MS-DOS and on a 386 Xenix system to name a few. REMIND
- Xshould compile on most systems without difficulty.
- X
- XOnce remind has been compiled, install it in your favourite system
- Xdirectory. Type "make install" to install the executable, and "make
- Xinstall.man" to install the manpage. If you want to install the "kall"
- Xscript, type "make install.kall"
- X
- XTwo shell scripts, "remind-all.csh" and "remind-all.sh" are provided.
- XThese allow automatic mailing of reminders to all users who create a
- X$HOME/.reminders file. These two scripts are equivalent; one is a
- X"sh" script and the other is a "csh" script. Pick the one you want to
- Xuse, and follow the instructions in the opening comments of the
- Xscript.
- X
- XA shell script called "kall" is provided which kills processes
- Xspecified by command name rather than process ID. You may have to
- Xedit it to work on your system, since the output of "ps" is not
- Xportable. You can use this script to kill all background remind
- Xprocesses in your .logout script by using "kall remind" Note that this
- Xversion of "kall" is different from the version of kall distributed
- Xwith 2.2 - the new version requires an exact match of command name,
- Xnot just a command name which contains the specified
- Xstring.
- X
- X--
- XDavid F. Skoll <dfs@doe.carleton.ca>
- END_OF_FILE
- if test 2180 -ne `wc -c <'README.UNIX'`; then
- echo shar: \"'README.UNIX'\" unpacked with wrong size!
- fi
- # end of 'README.UNIX'
- fi
- if test -f 'nextdate.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'nextdate.c'\"
- else
- echo shar: Extracting \"'nextdate.c'\" \(8719 characters\)
- sed "s/^X//" >'nextdate.c' <<'END_OF_FILE'
- X#include "defines.h"
- X#include "globals.h"
- X#include "protos.h"
- X
- X/***************************************************************/
- X/* */
- X/* int TryNextDate(int *retday, int *retmon, int *retyr, */
- X/* int startday, int startmon, int startyr, */
- X/* int conday, int conmon, int conyr, */
- X/* int wkday, int cons, int inc) */
- X/* */
- X/* This function tries to find the next date satisfying */
- X/* the given constraints. Returns */
- X/* 0 for success. Returns non-zero if a constraint would */
- X/* be violated. Note that if DAY and WEEKDAY are both */
- X/* constrained, then MONTH and YEAR may be violated. */
- X/* Otherwise, all constraints are honoured. */
- X/* The starting point for the search is thisday, etc. */
- X/* */
- X/* If inc is non-zero, then the search begins from the day */
- X/* after the specified date. Note that this function assumes */
- X/* that the given date is valid. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint TryNextDate(int *retday, int *retmon, int *retyr,
- X int d, int m, int y,
- X int conday, int conmon, int conyr,
- X int wkday, int cons, int inc)
- X#else
- Xint TryNextDate(retday, retmon, retyr, d, m, y, conday, conmon, conyr,
- X wkday, cons, inc)
- X int *retday, *retmon, *retyr, d, m, y, conday, conmon, conyr, wkday, cons, inc;
- X
- X#endif
- X
- X{
- X int jul, jul2;
- X int dd = d, mm = m, yy = y;
- X
- X if (inc)
- X {
- X d++;
- X if (d > DaysInMonth(m, y)) {
- X m++; d = 1;
- X if (m > 11) {
- X y++; m = 0;
- X }
- X }
- X }
- X
- X
- X switch (cons & 15) {
- X
- X case 0: /* No constraints - just use the start date */
- X *retday = d;
- X *retmon = m;
- X *retyr = y;
- X return 0;
- X
- X case 1: /* Day constrained to be d */
- X *retday = conday;
- X if (d > conday) {
- X m++;
- X if (m > 11) {y++; m=0;}
- X }
- X while (conday > DaysInMonth(m, y)) {
- X m++;
- X if (m > 11) {y++; m=0;}
- X }
- X *retmon = m;
- X *retyr = y;
- X return 0;
- X
- X case 2: /* Month constrained to be m */
- X *retmon = conmon;
- X if (m > conmon) {y++; d = 1;}
- X else if (m < conmon) d = 1;
- X *retday = d;
- X *retyr = y;
- X return 0;
- X
- X case 3: /* Month and day constrained */
- X *retmon = conmon;
- X *retday = conday;
- X if (m > conmon || (m == conmon && d > conday)) y++;
- X while (conday > DaysInMonth(conmon, y)) y++;
- X *retyr = y;
- X return 0;
- X
- X case 4: /* Year alone constrained */
- X if (y > conyr) return 1;
- X *retyr = conyr;
- X if (y < conyr) {
- X *retmon = 0;
- X *retday = 1;
- X }
- X else {
- X *retmon = m;
- X *retday = d;
- X }
- X return 0;
- X
- X case 5: /* Year and day constrained */
- X if (y > conyr) return 1;
- X *retyr = conyr;
- X *retday = conday;
- X if (y < conyr) {
- X *retmon = 0;
- X return 0;
- X }
- X if (d > conday) {
- X m++;
- X if (m > 11) return 1;
- X }
- X while (conday > DaysInMonth(m, y)) {
- X m++;
- X if (m > 11) return 1;
- X }
- X *retmon = m;
- X return 0;
- X
- X case 6: /* Year and month constrained */
- X if (y > conyr || (y == conyr && m > conmon)) return 1;
- X *retyr = conyr;
- X *retmon = conmon;
- X if (y < conyr || (y == conyr && m < conmon)) {
- X *retday = 1;
- X return 0;
- X }
- X *retday = d;
- X return 0;
- X
- X case 7: /* Year, month and day constrained */
- X *retday = conday;
- X *retmon = conmon;
- X *retyr = conyr;
- X if (y > conyr || (y == conyr && m > conmon) ||
- X (y == conyr && m == conmon && d > conday)) return 1;
- X return 0;
- X
- X case 8: /* Only the weekday constrained. Let's go to Julian mode */
- X jul = Julian(d, m, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X
- X case 9: /* GASP! day and weekday constrained .. bleah! */
- X /* First, try last month. */
- X jul2 = Julian(d, m, y);
- X if (m != 0 || y != BASE)
- X {
- X mm--;
- X if (mm < 0) {yy--; mm = 11;}
- X
- X /* If there are fewer days in month than required, it
- X can't possibly match. */
- X if (conday <= DaysInMonth(mm, yy)) {
- X jul = Julian(conday, mm, yy);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X if (jul >= jul2) { /* SUCCESS! */
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X }
- X }
- X /* Didn't work - try this month */
- X if (conday <= DaysInMonth(m, y)) {
- X jul = Julian(conday, m, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X if (jul >= jul2) { /* SUCCESS! */
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X }
- X /* Argh! Try next available month */
- X mm = m;
- X yy = y;
- X do {
- X mm++;
- X if (mm > 11) {mm = 0; yy++;}
- X } while (conday > DaysInMonth(mm, yy));
- X jul = Julian(conday, mm, yy);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X
- X case 10: /* Month and Weekday constrained */
- X if (m < conmon) {
- X jul = Julian(1, conmon, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X } else if (m == conmon) {
- X jul = Julian(d, conmon, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X if (*retmon != conmon) {
- X jul = Julian(1, conmon, y+1);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X }
- X return 0;
- X } else { /* m > conmon */
- X jul = Julian(1, conmon, y+1);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X
- X case 11: /* Day, Month and Weekday constrained */
- X jul2 = Julian(d, m, y);
- X
- X /* Blip up to next valid year */
- X while (conday > DaysInMonth(conmon, y)) y++;
- X
- X /* Try this year */
- X jul = Julian(conday, conmon, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X if (jul >= jul2) {
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X
- X /* Must be next year */
- X jul = Julian(conday, conmon, y+1);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X
- X case 12: /* Weekday and year specified */
- X if (y > conyr) return 1;
- X if (y == conyr) {mm = m; dd = d;} else {mm = 0; dd = 1;}
- X jul = Julian(dd, mm, conyr);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X if (*retyr == conyr) return 0; else return 1;
- X
- X case 13: /* Weekday, year and day specified */
- X if (y > conyr+1 || (y > conyr && m>0)) return 1;
- X jul2 = Julian(d, m, y);
- X if (y > conyr ) {
- X jul = Julian(conday, 11, conyr);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X if (jul >= jul2) {
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X } else if (y < conyr) {
- X jul = Julian(conday, 0, conyr);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X else {
- X /* Try last month */
- X if (m > 0) {
- X mm = m - 1;
- X while (conday > DaysInMonth(mm, y)) mm--;
- X jul = Julian(conday, mm, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X if (jul >= jul2) {
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X }
- X /* Try this month */
- X if (conday <= DaysInMonth(m,y)) {
- X jul = Julian(conday, m, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X if (jul >= jul2) {
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X }
- X /* Try next month */
- X if (m == 11) return 1;
- X m++;
- X while (conday > DaysInMonth(m, y)) m++;
- X jul = Julian(conday, m, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X
- X case 14: /* Weekday, Month and Year specified */
- X if (y > conyr || (y == conyr && m > conmon)) return 1;
- X if (conyr > y || (conyr == y && conmon > m)) {
- X jul = Julian(1, conmon, conyr);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X if (*retmon == conmon) return 0; else return 1;
- X } else {
- X jul = Julian(d, m, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X if (*retmon == conmon) return 0; else return 1;
- X
- X }
- X
- X case 15: /* Weekday, day, month and year specified */
- X jul2 = Julian(d, m, y);
- X jul = Julian(conday, conmon, conyr);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X if (jul < jul2) return 1;
- X return 0;
- X }
- X}
- END_OF_FILE
- if test 8719 -ne `wc -c <'nextdate.c'`; then
- echo shar: \"'nextdate.c'\" unpacked with wrong size!
- fi
- # end of 'nextdate.c'
- fi
- if test -f 'remind.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'remind.1'\"
- else
- echo shar: Extracting \"'remind.1'\" \(40229 characters\)
- sed "s/^X//" >'remind.1' <<'END_OF_FILE'
- X.TH REMIND 1 "18 February 1991"
- X.UC 4
- X.SH NAME
- Xremind \- a sophisticated reminder service
- X.SH SYNOPSIS
- X.B remind
- X[\fB\-n | \fB\-d\fR | \fB\-p\fR | \fB\-c\fR\fIn\fR [\fB\-w\fR\fIn\fR | \fB\-s\fR]]
- X[\fB\-voraq\fR]
- X.I filename
- X[\fIdate\fR]
- X.SH DESCRIPTION
- X.B remind
- Xreads the supplied
- X.I filename
- Xfor a list of reminders, and then issues reminders appropriate for
- Xthe current date.
- XEach reminder can consist of a message sent to standard output, or
- Xa program to be executed.
- X.SH OPTIONS
- X.TP
- X.B \-n
- XThe \fB\-n\fR flag causes \fBremind\fR to print the \fInext\fR occurrence
- Xof each reminder in a simple calendar format. You can sort this by date by
- Xpiping the output through \fBsort(1)\fR.
- X.TP
- X.B \-d
- XThe
- X.B \-d
- Xflag causes
- X.B remind
- Xto enter a debugging mode.
- XIn this mode, each reminder in the reminder file is examined and its
- Xtrigger date is printed to standard output. Also, some consistency
- Xchecking is done, and warnings are issued about constructs which could
- Xresult in slow execution times.
- X.TP
- X.B \-p
- XThe
- X.B \-p
- Xflag causes
- X.B remind
- Xto go into
- X.I purge
- Xmode. This mode is incompatible with the
- X.B \-d
- Xflag. It causes
- X.B remind
- Xto scan the reminder file and echo all reminders which have not expired
- Xto the standard output. All expired reminders are echoed to the standard
- Xerror stream.
- X.TP
- X.B \-c\fR\fIn\fR
- XThe
- X.B \-c
- Xflag causes \fBremind\fR to generate a calendar with reminders indicated on
- Xthe calendar. The calendar printout is formatted and sent to standard output.
- XIf you supply a number \fIn\fR from 1 to 12,
- Xthen a calendar will be generated for
- X\fIn\fR months, starting with the current month. The default is to
- Xproduce a calendar for one month only. The
- X.B \-c
- Xoption is not compatible with the \fB\-p\fR or \fB\-d\fR options.
- X.TP
- X.B \-w\fR\fIn\fR
- XThe \fB\-w\fR flag, when used in conjunction with \fB\-c\fR,
- Xcauses \fBremind\fR to format the calendar for a device
- Xwhose output width is \fIn\fR columns. The default is to produce a calendar
- Xfor an 80-column device.
- X.TP
- X.B \-s
- XThe \fB\-s\fB flag, when used in conjunction with \fB\-c\fR,
- Xcauses \fBremind\fR to send an unformatted "simple
- Xcalendar" listing to standard output. This can be used if you wish to
- Xformat the calendar with another program rather than using \fBremind\fR's
- Xbuilt-in calendar format.
- X.TP
- X.B \-v
- XThe
- X.B \-v
- Xflag causes the debugging messages caused by
- X.B \-d
- Xto be printed in a verbose manner. Also, any error messages issued by
- X.B remind
- Xare printed in verbose format.
- X.TP
- X.B \-o
- XThe
- X.B \-o
- Xflag causes
- X.B remind
- Xto ignore any
- X.B ONCE
- Xdirectives in the reminder file.
- X.TP
- X.B \-r
- XThe
- X.B \-r
- Xflag causes
- X.B remind
- Xto ignore any
- X.B RUN
- Xdirectives in the reminder file.
- X.TP
- X.B \-a
- XThe
- X.B \-a
- Xoption causes
- X.B remind
- Xnot to issue
- X.B AT
- Xreminders when the reminder file is read and processed, providing the
- X.B AT
- Xreminders would normally be queued. This allows you to have
- X.B remind
- Xqueue
- X.B AT
- Xreminders without triggering them when it reads the file.
- X.TP
- X.B \-q
- XThe
- X.B \-q
- Xflag causes
- X.B remind
- Xnot to queue
- X.B AT
- Xreminders for triggering later in the day. This prevents
- X.B remind
- Xfrom running as a daemon and popping up reminders as they are triggered.
- X.PP
- XIf you supply a
- X.I date
- Xon the command line, it must consist of
- X.I day month year
- Xwhere
- X.I day
- Xis the day of the month,
- X.I month
- Xis (at least the first three letters of) the English name of the month,
- Xand
- X.I year
- Xis a year (all 4 digits) from 1990 to 2075. These components can appear
- Xin any order, but must be separated by spaces. If a date is supplied,
- X.B remind
- Xuses it rather than the actual system date as its notion of "today." You
- Xcan use this feature to test how reminders will appear in the future, or
- Xto produce a calendar for any month you choose.
- X.SH REMINDER FILES
- X.B Remind
- Xuses scripts called
- X.I reminder files
- Xto control its operation. A sample reminder file is shown below:
- X.PP
- X.nf
- X #!/usr/local/bin/remind
- X # Sample file
- X BANNER Hi there. Here are your reminders:
- X
- X # First some birthdays
- X REM 6 Jan MSG David's birthday.
- X REM 23 Nov +10 MSG El's birthday is %a.
- X
- X # Next some housekeeping
- X REM 1 -1 OMIT Sat Sun RUN do_backup
- X
- X # Introduce some holidays
- X OMIT 25 Dec +2 MSG %"Christmas%" is %b.
- X OMIT 1 July MSG Canada Day
- X OMIT 22 Nov 1990 # American Thanksgiving
- X
- X # Business things
- X REM 23 Nov 1990 +2 AT 10:00 +30 *15 MSG \\
- X %"Meeting with Bill%" at %1 %b.%_Bring papers!
- X
- X.fi
- X.PP
- XNote that
- X.B remind
- Xignores blank lines and lines beginning with "#". If the character '\\'
- Xis the LAST character on the line, it is treated as a continuation
- Xcharacter. You can string many lines together using this character.
- XNote that if you use line continuation, then
- X.B remind
- Xuses the line number of the last line when printing diagnostic messages.
- X.PP
- XCommands, names of months, etc. can be typed in any
- Xmixture of upper- and lower-case. The convention I use is to
- Xuse upper-case for
- X.B remind
- Xtokens like
- X.I
- XMSG, OMIT,
- Xetc., and mixed case for other words like
- X.I January
- Xand
- X.I Sunday.
- X.SH THE REM COMMAND
- XThe most-used command in a reminder file is the
- X.I REM
- Xcommand. This command is used to denote a reminder. There are many
- Xforms of the
- X.I REM
- Xcommand; they are represented by:
- X.PP
- X.RS
- XREM [ONCE] [\fIdate_spec\fR]
- X[\fIdelta\fR]
- X[\fIback\fR]
- X[\fIrepeat\fR]
- X[\fISKIP\fR | \fIBEFORE\fR | \fIAFTER\fR]
- X[OMIT \fIomit_list\fR]
- X[AT \fItime\fR [\fItdelta\fR] [\fItrepeat\fR]]
- X[UNTIL \fIexpiry_date\fR]
- XMSG|RUN
- X.I body
- X.RE
- X.PP
- XThe parts of the \fIREM\fR command can be specified in any order, except
- Xthat the \fIbody\fR must come immediately after the \fIMSG\fR or \fIRUN\fR
- Xkeyword.
- X.SH DATE SPECIFICATIONS
- XThe
- X.I date_spec
- Xconsists of zero to four parts. These parts are
- X.I day
- X(day of month),
- X.I month
- X(month name),
- X.I year
- Xand
- X.I weekday.
- X.I Month
- Xand
- X.I weekday
- Xare the English names of months and weekdays. At least the first three
- Xcharacters must be used. Case is irrelevant. The following are examples
- Xof the various parts of a
- X.I date_spec:
- X.TP
- X.I day:
- X1, 22, 31, 14, 3
- X.TP
- X.I month:
- XJANUARY, feb, March, ApR, may, Aug
- X.TP
- X.I year:
- X1990, 1993, 2030, 95 (interpreted as 1995). The year can range
- Xfrom 1990 to 2075.
- X.TP
- X.I weekday:
- XMonday, tue, Wed, THU, Friday, saturday, sundAy
- X.PP
- XNote that there can be several
- X.I weekday
- Xcomponents separated by spaces in a
- X.I date_spec.
- X.PP
- X.B INTERPRETATION OF DATE SPECIFICATIONS
- X.PP
- XThe following examples show how date specifications are interpreted.
- X.PP
- X1. Null date specification - the reminder is triggered every day.
- XThe trigger date for a specific run is simply the current system date.
- X.PP
- X2. Only
- X.I day
- Xpresent. The reminder is triggered on the specified day of each month.
- XThe trigger date for a particular run is the closest such day to the
- Xcurrent system date. For example:
- X.nf
- X REM 1 MSG First of every month.
- X REM 31 MSG 31st of every month that has 31 days.
- X.fi
- X.PP
- X3. Only
- X.I month
- Xpresent. The reminder is triggered every day of the specified month.
- XExample:
- X.nf
- X REM Feb MSG Every day in February
- X.fi
- X.PP
- X4.
- X.I day
- Xand
- X.I month
- Xpresent. Examples:
- X.nf
- X REM 6 Jan MSG Every 6th of January
- X REM Feb 29 MSG Every 29th of February
- X.fi
- X.PP
- X5. Only
- X.I year
- Xpresent. Example:
- X.nf
- X REM 1991 MSG Every day in 1991
- X.fi
- X.PP
- X6.
- X.I year
- Xand
- X.I day
- Xpresent. Examples:
- X.nf
- X REM 1 1990 MSG 1st of every month in 1990
- X REM 1992 23 MSG 23rd of every month in 1992
- X.fi
- X.PP
- X7.
- X.I year
- Xand
- X.I month
- Xpresent. Examples:
- X.nf
- X REM Feb 1991 MSG Every day in Feb 1991
- X REM 1992 September MSG Every day in Sept 1992
- X.fi
- X.PP
- X8.
- X.I year, month
- Xand
- X.I day
- Xpresent. Examples:
- X.nf
- X REM 8 Jan 1991 MSG 8th January 1991.
- X REM 1992 March 9 MSG 9th March 1992.
- X.fi
- X.PP
- X9.
- X.I weekday
- Xonly. Examples:
- X.nf
- X REM Sat MSG Every Saturday
- X REM Mon Tue Wed Thu Fri MSG Every working day
- X REM Monday Wednesday MSG Every Monday and Wednesday
- X.fi
- X.PP
- X10.
- X.I weekday
- Xand
- X.I day
- Xpresent. Examples:
- X.nf
- X REM Sat 1 MSG First Saturday of every month
- X REM Mon Tue Wed Thu Fri 15 \\
- X MSG 1st working day after 15th of every month
- X.fi
- X.PP
- X11.
- X.I weekday
- Xand
- X.I month
- Xpresent. Examples:
- X.nf
- X REM Mon March MSG Every Monday in March
- X REM Mon Tue Wed Thu Fri Feb MSG Every working day in February
- X.fi
- X.PP
- X12.
- X.I weekday, month
- Xand
- X.I day
- Xpresent. Examples:
- X.nf
- X REM Mon 1 March MSG First Monday in March
- X REM Sat Sun 15 July MSG First Sat or Sun on or after 15 July
- X.fi
- X.PP
- X13.
- X.I weekday
- Xand
- X.I year
- Xpresent. Example:
- X.nf
- X REM Sat Sun 1991 MSG Every Saturday and Sunday in 1991
- X.fi
- X.PP
- X14.
- X.I weekday, day
- Xand
- X.I year
- Xpresent. Examples:
- X.nf
- X REM Mon 15 1990 MSG 1st Mon after 15th of every month in 1990
- X REM Mon Tue Wed Thu Fri 1 1990 \\
- X MSG 1st working day of every month in 1990
- X.fi
- X.PP
- X15.
- X.I weekday, month
- Xand
- X.I year
- Xpresent. Example:
- X.nf
- X REM Mon Wed 1991 Feb MSG Every Mon and Wed in Feb 1991.
- X.fi
- X.PP
- X16.
- X.I weekday, day, month
- Xand
- X.I year
- Xpresent. Example:
- X.nf
- X REM Mon Tue Wed Thu Fri 28 Oct 1990 \\
- X MSG 1st working day on or after 28 October 1990.
- X.fi
- X.PP
- XNote that when
- X.I weekday
- Xand
- X.I day
- Xare specified,
- X.B remind
- Xchooses the first date on or after the specified
- X.I day
- Xwhich also satisfies the
- X.I weekday
- Xconstraint. It does this by picking the first date on or after the specified
- X.I day
- Xwhich is listed in the list of
- X.I weekdays.
- XThus, a reminder like:
- X.PP
- X.nf
- X REM Mon Tue 28 Oct 1990 MSG Hi
- X.fi
- X.PP
- Xwould be issued only on Monday, 29 October, 1990. It would not be issued
- Xon Tuesday, 30 October, 1990, since the 29th is the first date to satisfy
- Xthe
- X.I weekday
- Xconstraints.
- X.PP
- X.B BACKWARD SCANNING
- X.PP
- XSometimes, you need to incorporate "backward scanning" into your date
- Xspecification. This is accomplished with the
- X.I back
- Xpart of the reminder specification. If present, the
- X.I back
- Xis specified as a number preceded by one or two minus signs. This causes
- X.B remind
- Xto compute the trigger date as usual, and then move back the specified
- Xnumber of days. For example:
- X.PP
- X.nf
- X REM Mon 1 -7 MSG Last Monday of every month.
- X.fi
- X.PP
- XThis works by finding the first Monday of every month, and then moving
- X"back" seven days. This results in the last Monday of the previous
- Xmonth. (Warning: If you have global
- X.I OMITs,
- Xthis might not work - see
- Xthe
- X.I OMIT
- Xcommand. In this case, you can use the "definite \fIback\fR" which consists
- Xof a number preceded by two minus signs like \-\-7)
- X.PP
- XAnother example is:
- X.PP
- X.nf
- X REM 1 -1 MSG Last day of every month.
- X.fi
- X.PP
- XSince we don't know how many days are in a month, to get to the last day
- Xof a month, we go to the first day of the next month and then move back
- Xone day.
- X.PP
- X.B Remind
- Xwill automatically scan forwards and backwards until it finds a suitable
- Xtrigger date. Note that large
- X.I back
- Xvalues can lead to a lot of backtracking and slow the execution of
- X.B remind.
- X.PP
- X.B ADVANCE WARNING
- X.PP
- X.B Remind
- Xcan warn you of an upcoming reminder as far in advance as you desire. This
- Xis specified by a
- X.I delta,
- Xwhich is a positive number preceded by one or two "+" signs. For example:
- X.PP
- X.nf
- X REM 8 Jan 1992 +3 MSG Test1
- X REM 1 +1 MSG Test2
- X.fi
- X.PP
- XThe reminder "Test1" will be triggered on the 8th of January, 1992, as well
- Xas the 3 days preceding it. All told, "Test1" will be triggered on the
- X5th through the 8th of January, 1992.
- X.PP
- XThe reminder "Test2" will be triggered on the first day of every month, as
- Xwell as the day before. In effect, "Test2" will be triggered on the first
- Xand last day of every month.
- X.PP
- X.I Delta
- Xand
- X.I back
- Xcan be combined:
- X.PP
- X.nf
- X REM Mon 1 --7 ++3 MSG Test3
- X.fi
- X.PP
- XThe reminder "Test3" will be triggered on the last Monday of every month,
- Xas well as the three days preceding it.
- X.PP
- XSee "The OMIT Command" for an explanation of the distinction between the "-"
- Xand "--" forms of the \fIback\fR, and the "+" and "++" forms of the
- X\fIdelta\fR.
- X.PP
- X.B REPEATING REMINDERS
- X.PP
- XThe
- X.I repeat
- Xcomponent in a reminder is a number preceded by an asterisk; for example,
- X"*14". The
- X.I repeat
- Xis used to remind you of events which occur regularly after a specified
- Xstart date. For example, suppose you get paid every second Thursday,
- Xand that your last payday was 8 November 1990. The following reminder
- Xwould remind you of each payday 3 days in advance:
- X.PP
- X.nf
- X REM 8 Nov 1990 *14 +3 MSG Payday is %b!
- X.fi
- X.PP
- XThe
- X.I repeat
- Xcomponent of "*14" would cause the reminder to be triggered every 14
- Xdays from the start date.
- X.PP
- XIn order to use a
- X.I repeat,
- Xyou must fully specify the start date. That means that if
- Xyou use a
- X.I repeat,
- Xyou must specify the
- X.I month, day
- Xand
- X.I year.
- XYou can also specify
- X.I weekday, back
- Xand
- X.I local OMITs
- Xbut these only affect the calculation of the start date. Once the
- Xstart date is calculated, the reminder is issued regularly every
- X.I repeat
- Xdays. Note, in particular, that once the start date is calculated,
- X.B remind
- Xignores local and global
- X.I OMITs
- Xwhen calculating the trigger date. The final trigger date is strictly
- Xa multiple of
- X.I repeat
- Xdays from the start date. The only exceptions are those cases covered
- Xby the \fIBEFORE, AFTER\fR and \fISKIP\fR keywords, discussed in the
- Xnext section.
- X.PP
- X.B THE BEFORE, AFTER AND SKIP KEYWORDS
- X.PP
- XShould a reminder's trigger date happen to fall on an OMITted day, the
- Xdefault action is to go ahead and trigger the reminder anyway. For example,
- Xsuppose you have a meeting every Tuesday. Consider the following:
- X.PP
- X.nf
- X OMIT 1 Jan MSG New Year's Day
- X OMIT 25 December MSG Christmas
- X REM Tue AT 13:00 MSG Code review meeting.
- X.fi
- X.PP
- XEven though Christmas 1990 is on a Tuesday, you will still be reminded
- Xof a code review meeting on that day. Surely that is not desirable. You
- Xcan tell \fBremind\fR to skip reminders which fall on OMITted days with the
- X.I SKIP
- Xkeyword. Assuming we have the same \fIOMIT\fR commands, then:
- X.PP
- X.nf
- X REM Tue SKIP AT 13:00 MSG Code review meeting.
- X.fi
- X.PP
- Xwould be triggered every Tuesday, but not on Christmas or New Year's
- XDay, because both of these holidays happen to fall on Tuesdays.
- X.PP
- XIn some situations, we don't want to skip the reminder; we want to move
- Xit to just before or just after a holiday. Consider these examples:
- X.PP
- X.nf
- X REM Fri AFTER OMIT Sat Sun MSG Do your backup!
- X.fi
- X.PP
- XThis reminder is normally triggered every Friday. However, if a particular
- XFriday happens to be a holiday, it will be triggered on the Monday after
- Xthe holiday instead. Note that the \fIAFTER\fR keyword keeps scanning
- Xforwards until it hits a day which is not in the global or local \fIOMIT\fR
- Xlists. (Of course, if both the Friday and Monday are holidays, then the
- Xreminder would be deferred until Tuesday, and so on.)
- X.PP
- X.nf
- X REM Fri BEFORE MSG Do your backup!
- X.fi
- X.PP
- XThis is similar, except that the reminder is issued on the previous Thursday
- Xif a particular Friday happens to be a holiday. This form, too, will
- Xmove back to Wednesday if Thursday also happens to be a holiday, and so on.
- X.PP
- XNote: These keywords skip both local and global \fIOMIT\fRs. Also,
- X\fBremind\fR will complain about certain illegal constructions, such as:
- X.PP
- X.nf
- X REM Mon SKIP OMIT Mon MSG Impossible!
- X.fi
- X.PP
- XIf \fBremind\fR makes too many attempts to find a trigger date for
- Xcertain forms, it assumes that no satisfiable date exists, and will warn
- Xyou to check the date specification. In practice, this should never happen.
- X.PP
- X.B THE UNTIL KEYWORD
- X.PP
- XThe \fIUNTIL\fR keyword can be used to force a reminder to expire at a
- Xparticular date. It must be followed by a \fIyear\fR, \fImonth\fR and
- X\fIday\fR specifying the expiry date. Here are some examples:
- X.PP
- XSuppose you have a conference from 25 Feb 1991 to 1 March 1991. You
- Xcould use:
- X.PP
- X.nf
- X REM 25 Feb 1991 *1 UNTIL 1 Mar 1991 MSG Conference today!
- X.fi
- X.PP
- XYou must include the "*1" to have the reminder repeated every day
- Xduring the conference. If you did not include the "*1", then the
- Xreminder would only have been issued on 25 Feb 1991.
- X.PP
- XSuppose you have jury duty from 4-15 March 1991, not including weekends.
- XSuppose further that you wish to be reminded of this duty starting on 1
- XMarch 1991 (hence the "++3"): (See the section "Substitution" for an
- Xexplanation of all the percent signs.)
- X.PP
- X.nf
- X REM 4 Mar 1991 ++3 *1 OMIT Sat Sun SKIP UNTIL 15 Mar 1991 \\
- X MSG %"Jury duty%" %b.
- X.fi
- X.PP
- XFinally, suppose you have a class every Tuesday and Thursday until 30 May
- X1991:
- X.PP
- X.nf
- X REM Tue Thu UNTIL 30 May 1991 MSG Class tonight.
- X.fi
- X.PP
- X.B THE MSG KEYWORD
- X.PP
- XThe
- X.I MSG
- Xkeyword causes the remaining part of the line to be passed through a
- Xsubstitution filter and then printed to standard output whenever the
- Xreminder is triggered. See the section "Substitution" for more information
- Xabout the substitution filter.
- X.PP
- X.B THE RUN KEYWORD
- X.PP
- XThe
- X.I RUN
- Xkeyword causes the remaining part of the line to be passed through the
- Xsubstitution filter and then passed to the default shell for execution
- Xwhenever the reminder is triggered. If the
- X.B \-r
- Xcommand-line option is specified, all
- X.I REM
- Xcommands with the
- X.I RUN
- Xkeyword are ignored.
- X.PP
- X.B
- XGETTING REMINDED ONLY ONCE PER DAY
- X.PP
- XIf you run
- X.B remind
- Xfrom your
- X.I .login
- Xscript, you may only want certain reminders to be run once per day, not
- Xonce per login. Typically, this is used to control
- X.I RUN
- Xcommands so that they only execute once per day. To specify this,
- Xplace the
- X.I ONCE
- Xkeyword in the reminder file. When
- X.B remind
- Xencounters a
- X.I ONCE
- Xkeyword, it checks the last-access date of the reminder file. If it is
- Xequal to the current date,
- X.B remind
- Xassumes that the reminder file has already been run once, and ignores the
- Xreminder. If you start
- X.B remind
- Xwith the
- X.B \-o
- Xcommand-line option,
- X.B remind
- Xignores the
- X.I ONCE
- Xkeyword.
- X.PP
- X.B LOCALLY OMITTING WEEKDAYS
- X.PP
- XA
- X.I REM
- Xcommand containing the
- X.I OMIT
- Xkeyword followed by a list of weekdays causes the
- X.I delta
- Xand
- X.I back
- Xto ignore the specified weekdays when counting days. This is called a
- X.I local OMIT.
- XFor example:
- X.PP
- X.nf
- X REM 1 +1 OMIT Sat Sun MSG Test4
- X.fi
- X.PP
- XThis reminder prints "Test4" on the first day of every month, as well
- Xas the previous day. If, however, the first day of the month falls on
- Xa Sunday or Monday, the reminder is also triggered on the previous
- XFriday, since the
- X.I delta
- Xof +1 does not count Saturdays or Sundays when moving backwards. Here's
- Xanother example:
- X.PP
- X.nf
- X REM 1 -1 +1 OMIT Sat Sun MSG Test5
- X.fi
- X.PP
- XThis reminder is triggered on the last working day of each month, as well
- Xas the working day preceding it. Let's look at it in detail:
- X.PP
- XThe
- X.I day
- Xof "1" specifies the first day of each month. The
- X.I back
- Xof "-1" tells
- X.B remind
- Xto go backwards by one day, not counting Saturday and Sunday as it moves.
- XThis takes us the the last working day of the preceding month, which is the
- Xtrigger date. The
- X.I delta
- Xof "+1" ensures that the reminder will be triggered on the day preceding
- Xthis trigger date also. Finally, if the trigger date happens to be
- Xa Monday, the
- X.I delta
- Xcombined with the
- X.I local OMIT
- Xcauses the reminder to be triggered on the Friday (and Saturday and Sunday)
- Xpreceding the trigger date.
- X.PP
- X.B THE AT KEYWORD
- X.PP
- XReminders with the
- X.I AT
- Xkeyword are called "timed reminders" or "AT reminders." The
- X.I AT
- Xkeyword must be followed by a
- X.I time,
- Xwhich is a time in 24-hour format, from 0:00 to 23:59. The
- X.I time
- Xmust be of the form \fIhh\fR:\fImm\fR.
- XAlso, after the
- X.I AT
- Xkeyword, you can supply a
- X.I tdelta
- Xand a
- X.I trepeat.
- XThese have the same form as a
- X.I delta
- Xand a
- X.I repeat.
- XIn other words, a
- X.I tdelta
- Xis a number preceded by a "+" sign, and a
- X.I trepeat
- Xis a number preceded by an asterisk.
- X.PP
- XWhen
- X.B remind
- Xencounters a timed reminder, it examines the actual trigger date. This
- Xis the date specified by the date_spec, not counting any
- X.I delta
- Xwhich may be present. If the trigger date is the same as the current
- Xdate, the timed reminder will be placed on a queue in addition to
- Xbeing triggered like a normal reminder. (If you supply the
- X.B \-a
- Xcommand-line option, a timed reminder which would be queued will not
- Xbe triggered like a normal reminder.) After
- X.B remind
- Xhas finished processing the reminder file, it starts up a background
- Xprocess to trigger all the queued timed reminders. As each reminder's
- Xtrigger time is reached, it is triggered. Thus, you can have
- X.B remind
- Xissue reminders just before important meetings or time-sensitive tasks.
- X.PP
- XThe
- X.I tdelta
- Xand
- X.I trepeat
- Xare interpreted in minutes. This is how they work:
- X.PP
- X.nf
- X REM AT 17:00 +60 *15 MSG Hello!
- X.fi
- X.PP
- XThis timed reminder has a trigger time of 5:00pm. It is also triggered
- Xone hour before 5:00pm (because of the
- X.I tdelta
- Xof +60)
- Xand every 15 minutes thereafter until 5:00pm (because of the
- X.I trepeat
- Xof +15.) All told, the reminder would be triggered at 4:00pm, 4:15pm,
- X4:30pm, 4:45pm and 5:00pm.
- X.PP
- X.nf
- X REM Fri AT 17:00 +45 *30 MSG Work ends at 5!!
- X.fi
- X.PP
- XThis timed reminder would be placed on the queue every Friday. It
- Xwould be triggered at 4:15pm, 4:45pm and 5:00pm every Friday. Note
- Xthat a timed reminder is always triggered at the time specified
- Xafter the
- X.I AT
- Xkeyword, even if the
- X.I tdelta
- Xis not a multiple of
- X.I trepeat.
- X.PP
- XIf a reminder has a regular
- X.I delta,
- Xit will not be queued unless the current system date equals the actual
- Xtrigger date. Thus:
- X.PP
- X.nf
- X REM Fri +1 AT 17:00 MSG Go home at 5:00!
- X.fi
- X.PP
- XOn Thursdays, this reminder would simply be treated as a regular reminder
- Xand printed. On Fridays, however, it would be queued for timed triggering.
- XNote that the
- X.B \-q
- Xcommand-line option causes
- X.B remind
- Xto treat timed reminders as normal reminders, and not queue them.
- X.SH THE OMIT COMMAND
- X.I OMIT
- Xexists as a separate command as well as a keyword within a
- X.I REM
- Xstatement. When used as a separate command, it is called a
- X.I global OMIT,
- Xand has the following form:
- X.RS
- XOMIT
- X.I day
- X.I month
- X[
- X.I year
- X]
- X.RE
- XThe arguments can be specified in any order.
- X.PP
- XThe form without the
- X.I year
- Xcomponent is used for holidays which fall on the same date each year.
- XFor example:
- X.PP
- X.nf
- X OMIT 25 December # Christmas
- X OMIT 1 January # New Year's Day
- X.fi
- X.PP
- X(Note that
- X.I OMIT
- Xcan have a following comment on the same line, unlike the
- X.I REM
- Xcommand.)
- X.PP
- XThe form with the
- X.I year
- Xcomponent is used for holidays which vary from year to year. For example:
- X.PP
- X.nf
- X OMIT 12 October 1990 # Columbus Day 1990
- X OMIT 22 November 1990 # Thanksgiving Day 1990
- X.fi
- X.PP
- XIn its debugging messages,
- X.B remind
- Xcalls the first form a
- X.I partially-specified global OMIT
- Xand the second form a
- X.I fully-specified global OMIT.
- X.PP
- XThe dates specified by
- X.I global OMITs
- Xare omitted by the
- X.I back
- Xand
- X.I delta
- Xportions of a reminders, in addition to any
- X.I local OMITs.
- XFor example:
- X.PP
- X.nf
- X OMIT 25 December
- X REM 26 +1 OMIT Sat Sun MSG Test6
- X.fi
- X.PP
- XThis would issue a reminder on the 26th of each month, as well as the
- Xpreceding working day. Also, on the 24th of December 1990, the reminder
- Xwould be issued. Even though the 25th of December 1990 is a Tuesday, the
- X.I global OMIT
- Xwould cause the
- X.I delta
- Xto skip it.
- X.PP
- XHowever, if you use the "--" and "++" forms of \fIback\fR and \fIdelta\fR,
- Xthen OMITted days are not skipped - strict date subtraction is performed.
- XThus, to have a reminder issued on the last Monday of every month, regardless
- Xof any \fIglobal OMITs\fR in force, you could use:
- X.PP
- X.nf
- X REM 1 Mon --7 MSG Forced to be last Monday in month
- X.fi
- X.PP
- XIf you want the reminder to be issued on the last Monday of every month,
- Xunless it is a holiday, in which case the reminder should be issued the
- Xfollowing Tuesday, use:
- X.PP
- X.nf
- X REM 1 Mon --7 AFTER MSG Example!
- X.fi
- X.PP
- X.I Global OMITs
- Xare in force for all reminders following them in the reminder file until
- Xa CLEAR-OMIT-CONTEXT or POP-OMIT-CONTEXT command is encountered. Thus,
- Xyou could have a series of reminders for which
- X.I global OMITs
- Xare inappropriate (such as birthdays or reminders which rely on
- X.I back
- Xto get to a specific weekday) ahead of any
- X.I global OMITs,
- Xwith business reminders (for which omission of holidays is appropriate)
- Xfollowing the
- X.I global OMITs.
- X.PP
- XFor convenience, you can include a \fIdelta\fR and a \fIMSG\fR or \fIRUN\fR
- Xtoken in a global \fIOMIT\fR. This is useful to avoid duplication of holiday
- Xentries. For example, the line:
- X.PP
- X.nf
- X OMIT 25 Dec +2 MSG %"Christmas%" is %b.
- X.fi
- X.PP
- Xis exactly equivalent to:
- X.PP
- X.nf
- X OMIT 25 Dec
- X REM 25 Dec +2 MSG %"Christmas%" is %b.
- X.fi
- X.SH CONTROLLING THE OMIT CONTEXT
- XIn many cases, it is convenient to temporarily change the \fIglobal OMITs\fR
- Xwhich are in force. This allows you to easily isolate holidays to act only
- Xon certain reminders, or to temporarily introduce a \fIglobal OMIT\fR for a
- Xspecial-case reminder. Three commands allow you to do this:
- X.PP
- X.I CLEAR-OMIT-CONTEXT
- Xdeletes all the \fIglobal OMITs\fR and starts you off with a clean slate.
- X.PP
- X.I PUSH-OMIT-CONTEXT
- Xsaves all the \fIglobal OMITs\fR on an internal stack and leaves the current
- X\fIglobal OMITs\fR in effect.
- X.PP
- X.I POP-OMIT-CONTEXT
- Xrestores the \fIglobal OMITs\fR which were in effect at the time of the last
- Xmatching \fIPUSH-OMIT-CONTEXT\fR command.
- X.PP
- XSuppose you have a block of reminders which require a clear OMIT context
- Xto work properly, and which also introduce several \fIglobal OMITs\fR which
- Xyou don't want to affect any other reminders. The following fragment shows
- Xhow to isolate these reminders:
- X.PP
- X.nf
- X # Sample fragment
- X PUSH-OMIT-CONTEXT # Save for later
- X CLEAR-OMIT-CONTEXT # Start out with clean slate
- X
- X # Block of reminders goes here
- X
- X POP-OMIT-CONTEXT # Restore the saved OMITs
- X # Remaining reminders go here
- X.fi
- X.SH THE INCLUDE COMMAND
- XThe
- X.I INCLUDE
- Xcommand has the following form:
- X.PP
- X.RS
- XINCLUDE
- X.I filename
- X.RE
- X.PP
- XThis causes
- X.B remind
- Xto suspend the current file and read the contents of the specified
- X.I filename.
- XOnce that file has been read,
- X.B remind
- Xcontinues reading the original file from where it left off.
- X.I INCLUDE
- Xcommands can be nested to a depth of 10.
- X.PP
- X.I INCLUDE
- Xallows you or someone else to maintain a file of holidays or system-wide
- Xreminders that everyone should get. For example, your reminder file could
- Xlook something like this:
- X.PP
- X.nf
- X #!/usr/local/bin/remind
- X #
- X # Place personal stuff here - birthdays, etc.
- X
- X # Now get system-wide global OMITS (holidays)
- X INCLUDE /usr/share/holidays
- X
- X # and system-wide reminders
- X INCLUDE /usr/share/reminders
- X
- X # Place local business stuff here.
- X.fi
- X.PP
- XThe
- X.I ONCE
- Xkeyword operates on the last-access date of the top-level file.
- XThe access dates of
- X.I INCLUDEd
- Xfiles are not used to control the operation of the
- X.I ONCE
- Xkeyword.
- X.SH SUBSTITUTION
- XBefore being processed, the body of a
- X.I REM
- Xcommand is passed through a substitution filter. The filter scans for
- Xsequences "%x" (where "x" is any letter and certain other characters)
- Xand performs substitutions as
- Xshown below. (All dates refer to the trigger date of the reminder.)
- X.TP
- X.B %a
- Xis replaced with "on \fIweekday, day month, year\fR"
- X.RS
- XFor example, consider the reminder:
- X.PP
- XREM 18 Oct 1990 +4 MSG Meeting with Bob %a.
- X.PP
- XOn 16 October 1990, it would print "Meeting with Bob on Thursday, 18 October,
- X1990."
- X.PP
- XOn 17 October 1990, it would print "Meeting with Bob tomorrow."
- X.PP
- XOn 18 October 1990, it would print "Meeting with Bob today."
- X.RE
- X.TP
- X.B %b
- Xis replaced with "in \fIdiff\fR day's time" where
- X.I diff
- Xis the
- X.B actual
- Xnumber of days between the current date and the trigger date.
- X(\fIOMITs\fR have no effect.)
- X.RS
- XFor example, consider:
- X.PP
- XREM 18 Oct 1990 +4 MSG Meeting with Bob %b.
- X.PP
- XOn 16 October 1990, it would print "Meeting with Bob in 2 days' time."
- X.PP
- XOn 17 October 1990, it would print "Meeting with Bob tomorrow."
- X.PP
- XOn 18 October 1990, it would print "Meeting with Bob today."
- X.RE
- X.TP
- X.B %c
- Xis replaced with "on \fIweekday\fR"
- X.RS
- XExample: REM 18 Oct 1990 +4 MSG Meeting with Bob %c.
- X.PP
- XOn 16 October 1990, it would print "Meeting with Bob on Thursday."
- X.PP
- XOn 17 October 1990, it would print "Meeting with Bob tomorrow."
- X.PP
- XOn 18 October 1990, it would print "Meeting with Bob today."
- X.RE
- X.TP
- X.B %d
- Xis replaced with "\fIday\fR", the day of the month.
- X.TP
- X.B %e
- Xis replaced with "on \fIdd/mm/yyyy\fR"
- X.TP
- X.B %f
- Xis replaced with "on \fImm/dd/yyyy\fR"
- X.TP
- X.B %g
- Xis replaced with "on \fIweekday, day month\fR"
- X.TP
- X.B %h
- Xis replaced with "on \fIdd/mm\fR"
- X.TP
- X.B %i
- Xis replaced with "on \fImm/dd\fR"
- X.TP
- X.B %j
- Xis replaced with "on \fIweekday, month day-th, year\fR" This form appends the
- Xcharacters "st", "nd", "rd" or "th" to the day of the month, as appropriate.
- X.TP
- X.B %k
- Xis replaced with "on \fIweekday, month day-th\fR"
- X.TP
- X.B %l
- Xis replaced with "on \fIyyyy/mm/dd\fR"
- X.TP
- X.B %m
- Xis replaced with "\fImonth\fR", the name of the month.
- X.TP
- X.B %n
- Xis replaced with the number (1 to 12) of the month.
- X.TP
- X.B %o
- Xis replaced with " (today)" if and only if the current system date is the same
- Xas the date being used by
- X.B remind
- Xas the current date. Recall that you can specify a date for
- X.B remind
- Xto use on the command line. This substitution is not generally useful in a
- X.I REM
- Xcommand, but is useful in a
- X.I BANNER
- Xstatement. (See the section "The BANNER Command.)
- X.TP
- X.B %p
- Xis replaced with "s" if the
- X.I diff
- Xbetween the current date and the trigger date is not 1. You can use this
- Xto construct reminders like:
- X.RS
- XREM 1 Jan +4 MSG %x day%p to go before New Year!
- X.RE
- X.TP
- X.B %q
- Xis replaced with "'s" if the
- X.I diff
- Xbetween the trigger date and the current date is 1. Otherwise, it is replaced
- Xwith "s'" This can be used as follows:
- X.RS
- XREM 1 Jan +4 MSG New Year in %x day%q time!
- X.RE
- X.TP
- X.B %r
- Xis replaced with the day of the month (01 to 31) padded with a leading zero
- Xif needed to pad to two digits.
- X.TP
- X.B %s
- Xis replaced with "st", "nd", "rd" or "th" depending on the day of the month.
- X.TP
- X.B %t
- Xis replaced with the number of the month (01 to 12) padded to two digits
- Xwith a leading zero.
- X.TP
- X.B %u
- Xis replaced with "on \fIweekday, day-th month, year\fR" This is similar
- Xto
- X.B %a
- Xexcept that "st", "nd", "rd" or "th" is added to the
- X.I day
- Xas appropriate.
- X.TP
- X.B %v
- Xis replaced with "on \fIweekday, day-th month\fR"
- X.TP
- X.B %w
- Xis replaced with "\fIweekday\fR", the name of the day of the week.
- X.TP
- X.B %x
- Xis replaced with the
- X.I diff
- Xbetween the current date and the trigger date. The
- X.I diff
- Xis defined as the actual number of days between these two dates;
- X.I OMITs
- Xare not counted. (Strict date subtraction is performed.)
- X.TP
- X.B %y
- Xis replaced with "\fIyear\fR", the year of the trigger date.
- X.TP
- X.B %z
- Xis replaced with "\fIyy\fR", the last two digits of the year.
- X.TP
- X.B %_
- X(percent-underscore) is replaced with a newline. You can use this to
- Xachieve multi-line reminders.
- X.TP
- X.B %1
- Xis replaced with "now", "\fIm\fR minutes from now", "\fIm\fR minutes ago",
- X"\fIh\fR hours from now", "\fIh\fR hours ago", "\fIh\fR hours and \fIm\fR
- Xminutes from now" or "\fIh\fR hours and \fIm\fR minutes ago", as appropriate
- Xfor a timed reminder. Note that unless you specify the \fB\-a\fR option,
- Xtimed reminders will be triggered like normal reminders, and thus a timed
- Xreminder which occurred earlier in the day may be triggered. This
- Xcauses the need for the "...ago" forms.
- X.TP
- X.B %2
- Xis replaced with "\fIhh\fR:\fImm\fRam" or "..pm" depending on the
- X.I AT
- Xtime of the reminder.
- X.TP
- X.B %3
- Xis replaced with "\fIhh\fR:\fImm\fR" in 24-hour format.
- X.TP
- X.B %4
- Xis replaced with "\fImm\fR" where \fImm\fR is the number of minutes between
- X"now" and the time specified by \fIAT\fR. If the \fIAT\fR time is
- Xearlier than the current time, then the result is negative.
- X.TP
- X.B %5
- Xis replaced with "\fIma\fR" where \fIma\fR is the absolute value of the number
- Xproduced by \fB%4\fR.
- X.TP
- X.B %6
- Xis replaced with "ago" or "from now", depending on the relationship between
- Xthe \fIAT\fR time and the current time.
- X.TP
- X.B %7
- Xis replaced with the number of hours between the \fIAT\fR time and the
- Xcurrent time. It is always non-negative.
- X.TP
- X.B %8
- Xis replaced with the number of minutes between the \fIAT\fR time and
- Xthe current time, after the hours (\fB%7\fR) have been subtracted out.
- XThis is a number ranging from 0 to 59.
- X.TP
- X.B %9
- Xis replaced with "s" if the value produced by \fB%8\fR is not 1.
- X.TP
- X.B %0
- Xis replaced with "s" if the value produced by \fB%7\fR is not 1.
- X.TP
- X.B %!
- Xis replaced with "is" if the current time is before the \fIAT\fR time,
- Xor "was" if it is after.
- X.TP
- X.B
- X%"
- X(percent-doublequote) is removed. This sequence is not
- Xused by the substitution filter,
- Xbut is used to tell \fBremind\fR which text to include in a calendar
- Xentry when the \fB\-c\fR option is chosen. See the section "Producing
- Xa Calendar"
- X.PP
- XNotes:
- X.TP
- Xo
- X.B Remind
- Xnormally prints a blank line after each reminder; if the last character
- Xof the body is '%', the blank line will not be printed.
- X.TP
- Xo
- XSubstitutions a, b, c, e, f, g, h, i, j, k, l, u and v all are replaced
- Xwith "today" if the current date equals the trigger date, or "tomorrow"
- Xif the trigger date is one day after the current date. Thus, they are
- X.B not
- Xthe same as substitutions built up from the simpler %w, %y, etc.
- Xsequences.
- X.TP
- Xo
- XAny of the substitutions dealing with time (0 through 9 and '!')
- Xproduce undefined results if used in a reminder which does not have
- Xan \fIAT\fR keyword. Also, if a reminder has a \fIdelta\fR and may
- Xbe triggered on several days, the time substitutions ignore the date. Thus,
- Xthe \fB%1\fR substitution may report that a meeting is in 15 minutes, for
- Xexample, even though it may only be in 2 days time, because a \fIdelta\fR has
- Xtriggered the reminder. It is recommended that you use the time substitutions
- Xonly in timed reminders with no \fIdelta\fR which are designed to be
- Xqueued for timed activation.
- X.TP
- Xo
- XCapital letters can be used in the substitution sequence, in which case
- Xthe first character of the substituted string is capitalized (if it is
- Xnormally a lower-case letter.)
- X.TP
- Xo
- XAll other characters following a "%" sign are simply copied. In particular,
- Xto get a "%" sign out, use "%%" in the body. To start the body of a reminder
- Xwith a space, use "% ", since
- X.B remind
- Xnormally scans for the first non-space character after a
- X.I MSG
- Xor
- X.I RUN
- Xtoken.
- X.SH PRODUCING A CALENDAR
- XIf you provide the \fB\-c\fR option, the \fBremind\fR will scan your
- Xreminder file and produce a calendar with your reminders entered on the
- Xappropriate dates.
- X.PP
- XWhen you produce a calendar, \fBremind\fR will pass the text
- Xthrough the substitution mechanism. However, you may indicate to \fBremind\fR
- Xwhich portions of the text should be placed in the calendar. This is done
- Xwith the \fB%"\fR sequence. Here's an example:
- X.PP
- X.nf
- X REM 6 Jan +6 MSG %"David's birthday%" is %a.
- X.fi
- X.PP
- XWhen you run \fBremind\fR normally, it executes the reminder as if the
- X.B
- X%"
- Xsequences were not there. When you produce a calendar with the \fB\-c\fR
- Xoption, however, only the text "David's birthday" is entered into the
- Xcalendar. For convenience, timed reminders are sorted by time before
- Xbeing entered into the calendar, and the time of each reminder is printed
- Xbefore the reminder text.
- X.PP
- XNote that by default, only \fIMSG\fR reminders are included in the calendar;
- X\fIRUN\fR reminders are ignored. However, if you explicitly place the %"
- Xescape sequences in a \fIRUN\fR reminder, then it will be included in the
- Xcalendar.
- XIf you indicate empty text for the calendar entry
- Xwith the sequence \fB%"%"\fR, then the reminder is ignored when producing
- Xthe calendar, whether is is a \fIMSG\fR or \fIRUN\fR type.
- X.PP
- XIf your reminder file has errors in it, when you produce a calendar, you
- Xwill get many error messages apparently coming from the file "*cache*"
- XThis is because \fBremind\fR caches the reminder file for efficient
- Xproduction of the calendar. Thus, you should check that your reminder
- Xfile is error-free (by running \fBremind\fR with the \fB\-d\fR option)
- Xbefore attempting to produce a calendar.
- X.PP
- XThe "Simple Calendar" format is useful if you want to format the calendar
- Xwith another program. You can save this output to a file or pipe it to
- Xyour formatting program. The output format is:
- X.PP
- X.nf
- X yyyy/mm/dd: hr:min \fIbody\fR
- X.fi
- X.PP
- XThe \fIhr:min\fR portion is present only if the reminder has an \fIAT\fR
- Xclause. You can produce this format by using the \fB\-s\fR option in
- Xconjunction with the \fB-c\fR option. The \fB\-n\fR option produces
- Xa listing in this format also; however, it is not sorted by date, and
- Xindicates the next occurrence of each reminder in the reminder file.
- X.SH THE BANNER COMMAND
- XWhen
- X.B remind
- Xissues reminders, it normally prints a message saying:
- X.PP
- X"Reminders for \fIweekday, day-th month, year\fR (today):"
- X.PP
- X(If you supply a date on the command line different from the system date,
- Xthe "(today)" portion is omitted.)
- X.PP
- XYou can change this default to anything you want with the
- X.I BANNER
- Xcommand. It should appear in the reminder file before any
- X.I REM
- Xcommands. (This is not enforced, but a
- X.I BANNER
- Xcommand encountered after a reminder has been triggered will be ignored.)
- X.PP
- XThe format of
- X.I BANNER
- Xis:
- X.PP
- XBANNER
- X.I string
- X.PP
- XThe
- X.I string
- Xis passed through the substitution mechanism described before, using the
- Xcurrent date and time for substitution. The standard banner is described by:
- X.PP
- X.nf
- X BANNER Reminders for %w, %d%s %m, %y%o:
- X.fi
- X.PP
- XYou can have a blank banner by using:
- X.PP
- X.nf
- X BANNER %
- X.fi
- X.PP
- X.SH PURGING REMINDER FILES
- XYou should periodically purge your reminder file of "expired"
- X.I REM
- Xcommands and global
- X.I OMITs.
- XThese are reminders which took place in the past and can never occur
- Xagain, or
- X.I OMITs
- Xwhich are for past years. Of course, only
- X.I REMs
- Xand
- X.I OMITs
- Xwith the
- X.I year
- Xspecified can ever expire.
- X.PP
- XTo purge your reminder file, run
- X.B remind
- Xin
- X.I purge
- Xmode. This mode simply echoes non-expired lines to standard output, and
- Xexpired lines to standard error. Thus, to purge a file, you could type:
- X.PP
- X.nf
- X REMIND -p notes.old > notes.new
- X.fi
- X.PP
- XThe file "notes.new" would contain all non-expired lines from "notes.old."
- XAll expired lines are echoed to the screen.
- X.I INCLUDEd
- Xfiles are read and processed, but not purged. You must purge each
- X.I INCLUDEd
- Xfile separately.
- X.PP
- XYou can supply a date on the command line when purging, but beware: If you
- Xsupply a date in the future, you may inadvertently purge lines which have not
- Xreally expired yet.
- X.SH DEBUGGING A REMINDER FILE
- XThe debug command-line option \-d is used to debug reminder files. It tells
- Xyou useful information about the reminder file. It displays the trigger date
- Xof each reminder, and places an asterisk by those which would be issued
- Xon the current date. It also informs you of
- X.I OMITs
- Xwhich have expired, and gives warnings about situations which could lead
- Xto long execution times or unexpected results.
- X.PP
- XAll debugging messages are sent to standard error.
- X.SH EXAMPLES OF REMINDERS
- XThis section is a sampling of what you can do with \fBremind\fR.
- X.PP
- X.nf
- X REM 5 Feb 1991 AT 14:00 +45 *30 \\
- X RUN mail -s "Meeting at %2" $LOGNAME </dev/null &
- X.fi
- X.PP
- XOn 5 February, 1991, this reminder will mail
- Xyou reminders of a 2:00pm meeting at 1:15,
- X1:45 and 2:00. The subject of the mail message will be "Meeting at 2:00pm"
- Xand the body of the message will be blank.
- X.PP
- X.nf
- X REM AT 17:00 RUN echo "5:00pm - GO HOME!" | xless -g +0+0 &
- X.fi
- X.PP
- XThis reminder will pop up an xless window at 5:00pm every day. The xless
- Xwindow will contain the line "5:00pm - GO HOME!"
- X.PP
- X.nf
- X REM AT 23:59 RUN (sleep 120; remind -a .reminders) &
- X.fi
- X.PP
- XThis reminder will run at one minute to midnight. It will cause a new
- Xremind process to start at one minute past midnight. This allows you to
- Xhave a continuous reminder service so you can work through the night and
- Xstill get timed reminders for early in the morning.
- X.PP
- X.nf
- X remind -c12 /dev/null 1 Jan 1991
- X.fi
- X.PP
- XThis invocation of \fBremind\fR will cause it to print a calendar for
- X1991, with all entries left blank.
- X.SH AUTHOR
- XDavid F. Skoll
- X.SH BUGS
- X.B Remind
- Xwas originally written for MS-DOS and ported to UNIX. It does some things
- Xin an ungainly way.
- X.PP
- XDate calculation algorithms are fairly "brute force."
- X.PP
- XThe MS-DOS version of \fBremind\fR does not support queuing or timed
- Xactivation of reminders. It does, however, support the other semantics
- Xof the \fIAT\fR keyword.
- X.PP
- X.B Remind
- Xhas some built-in limits on total line length (511 characters),
- Xthe length of an expanded \fIREM\fR body (511 characters), the number
- Xof global \fIOMIT\fRs, etc.
- END_OF_FILE
- if test 40229 -ne `wc -c <'remind.1'`; then
- echo shar: \"'remind.1'\" unpacked with wrong size!
- fi
- # end of 'remind.1'
- fi
- echo shar: End of archive 1 \(of 4\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 4 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-